package modularity.passiveDrift;

import java.util.LinkedList;

import ec.util.MersenneTwisterFast;

public class BasicMutatorWithNodeDuplication extends BasicMutator {

	protected double duplicationProb;
	
	public BasicMutatorWithNodeDuplication(double removeConnectionProb, double addConnectionProb, double addNodeProb, double duplicationProb) {
		super(removeConnectionProb, addConnectionProb, addNodeProb);
		this.duplicationProb = duplicationProb;
	}
	
	public void mutate(Genome<ConnectionGene> gen, MersenneTwisterFast random){
		BasicGenome genome = (BasicGenome) gen;
		
		removeConnectionMutation(genome, random);
		addConnectionMutation(genome, random);
		addNodeMutation(genome, random);
		
		duplicateNodeMutation(genome, random);
	}

	private void duplicateNodeMutation(BasicGenome genome,	MersenneTwisterFast random) {
		double prob = random.nextDouble();
		if(prob < duplicationProb){
			int index = random.nextInt(genome.getNumberOfNodes());
			int nodeId = genome.getNodeAt(index);
			
			int newNodeId = super.generateNextNodeId();
			
			LinkedList<ConnectionGene> connectionsWithGene = genome.getConnectionsWithNode(nodeId);
			for(ConnectionGene connection : connectionsWithGene){
				if(connection.getFromGene() == nodeId)
					genome.addConnection(new ConnectionGene(newNodeId, connection.getToGene()));
				else
					genome.addConnection(new ConnectionGene(connection.getFromGene(), newNodeId));
			}
		}
	}

}
